package zt.song.config;

import jakarta.annotation.Resource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.authentication.configuration.EnableGlobalAuthentication;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import zt.song.security.MyAccessDenied;
import zt.song.security.MyAuthFaile;
import zt.song.security.MyEntryPoint;

/**
 * @Author 宋伟宁
 * @Date 2023/11/18
 * @Version 1.0
 **/
@EnableWebSecurity
@Configuration

public class SecurityConfig {

    //登录失败的处理器
    @Resource
    private MyAuthFaile myAuthFaile;

    //权限不足的处理器
    @Resource
    private MyAccessDenied myAccessDenied;

    @Resource
    private MyEntryPoint myEntryPoint;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
         http
                 .authorizeHttpRequests(resp->
                         //放过登录请求
                          resp.requestMatchers("/login","/app/**").permitAll()
                                  //管理员
                                  .requestMatchers("/admin/**").hasAuthority("admin")//hasRole("admin")
                                  .requestMatchers("/user/**").hasAuthority("user")//hasRole("user")
                                  //用户
                                  //任何其它请求必须经过认证
                                  .anyRequest().authenticated()

                 );

         //配置登录业务逻辑
         http.formLogin( form->
                   form.loginPage("/login").permitAll()
                           //登录成功后
                           .defaultSuccessUrl("/index")
                            //错误的账号和密码
                           .failureHandler(this.myAuthFaile)
                 );

         //权限不足
         http.exceptionHandling( e-> e.accessDeniedHandler(this.myAccessDenied));
         //未登录
         http.exceptionHandling(e-> e.authenticationEntryPoint(this.myEntryPoint));
         http.csrf(Customizer.withDefaults());
         //让session失效
        http.logout(logout -> logout.invalidateHttpSession(true));
         return  http.build();
    }


    @Bean
    public PasswordEncoder passwordEncoder(){
        return  new BCryptPasswordEncoder();
    }


}
